#!/usr/bin/env python
"""
Security Configuration Checker for Django Access Control System

This script checks for common security misconfigurations and provides
recommendations for production deployment.

Usage:
    python check_security.py
"""

import os
import sys
from pathlib import Path

# Add the project root to Python path
project_root = Path(__file__).resolve().parent
sys.path.append(str(project_root))

# Setup Django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

try:
    import django
    django.setup()
    from django.conf import settings
except ImportError as e:
    print(f"❌ Error importing Django: {e}")
    print("Make sure you're in the correct directory and Django is installed.")
    sys.exit(1)

def check_secret_key():
    """Check SECRET_KEY configuration"""
    print("🔐 Checking SECRET_KEY...")
    
    if not settings.SECRET_KEY:
        print("❌ SECRET_KEY is not set!")
        return False
    
    if settings.SECRET_KEY.startswith('django-insecure-'):
        print("⚠️  WARNING: Using default insecure SECRET_KEY!")
        print("   Generate a new key with: python -c \"from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())\"")
        return False
    
    if len(settings.SECRET_KEY) < 50:
        print("⚠️  WARNING: SECRET_KEY is too short (should be at least 50 characters)")
        return False
    
    print("✅ SECRET_KEY looks good")
    return True

def check_debug_mode():
    """Check DEBUG setting"""
    print("\n🐛 Checking DEBUG mode...")
    
    if settings.DEBUG:
        print("⚠️  WARNING: DEBUG is True!")
        print("   Set DJANGO_DEBUG=False in production environment")
        return False
    
    print("✅ DEBUG is properly disabled")
    return True

def check_allowed_hosts():
    """Check ALLOWED_HOSTS configuration"""
    print("\n🌐 Checking ALLOWED_HOSTS...")
    
    if not settings.ALLOWED_HOSTS:
        print("❌ ALLOWED_HOSTS is empty!")
        print("   Add your domain names to DJANGO_ALLOWED_HOSTS")
        return False
    
    if 'localhost' in settings.ALLOWED_HOSTS or '127.0.0.1' in settings.ALLOWED_HOSTS:
        print("⚠️  WARNING: localhost/127.0.0.1 in ALLOWED_HOSTS")
        print("   Remove these in production environment")
        return False
    
    print(f"✅ ALLOWED_HOSTS configured: {settings.ALLOWED_HOSTS}")
    return True

def check_database():
    """Check database configuration"""
    print("\n💾 Checking database configuration...")
    
    db_engine = settings.DATABASES['default']['ENGINE']
    
    if 'sqlite3' in db_engine:
        print("⚠️  WARNING: Using SQLite database")
        print("   Consider PostgreSQL or MySQL for production")
        return False
    
    print(f"✅ Using production database: {db_engine}")
    return True

def check_security_headers():
    """Check security headers configuration"""
    print("\n🛡️  Checking security headers...")

    security_settings = [
        ('SECURE_SSL_REDIRECT', 'SSL redirect'),
        ('SECURE_HSTS_SECONDS', 'HSTS'),
        ('SECURE_CONTENT_TYPE_NOSNIFF', 'Content type nosniff'),
        ('SECURE_BROWSER_XSS_FILTER', 'XSS filter'),
        ('SESSION_COOKIE_SECURE', 'Secure session cookies'),
        ('CSRF_COOKIE_SECURE', 'Secure CSRF cookies'),
    ]

    all_good = True
    for setting_name, description in security_settings:
        if hasattr(settings, setting_name):
            value = getattr(settings, setting_name)
            if value:
                print(f"✅ {description} enabled")
            else:
                print(f"⚠️  {description} disabled")
                all_good = False
        else:
            print(f"⚠️  {description} not configured")
            all_good = False

    return all_good

def check_cors_configuration():
    """Check CORS configuration"""
    print("\n🌐 Checking CORS configuration...")

    if not hasattr(settings, 'CORS_ALLOWED_ORIGINS'):
        print("❌ CORS_ALLOWED_ORIGINS not configured!")
        return False

    cors_origins = getattr(settings, 'CORS_ALLOWED_ORIGINS', [])
    if not cors_origins:
        print("⚠️  No CORS origins configured")
        return False

    print(f"✅ CORS origins configured: {len(cors_origins)} origins")
    for origin in cors_origins[:3]:  # Show first 3
        print(f"   - {origin}")
    if len(cors_origins) > 3:
        print(f"   ... and {len(cors_origins) - 3} more")

    # Check for development origins in production
    if not settings.DEBUG:
        dev_origins = [origin for origin in cors_origins if 'localhost' in origin or '127.0.0.1' in origin]
        if dev_origins:
            print("⚠️  WARNING: Development origins found in production:")
            for origin in dev_origins:
                print(f"   - {origin}")
            return False

    return True

def check_websocket_configuration():
    """Check WebSocket configuration"""
    print("\n🔌 Checking WebSocket configuration...")

    # Check ASGI application
    if not hasattr(settings, 'ASGI_APPLICATION'):
        print("❌ ASGI_APPLICATION not configured!")
        return False

    print(f"✅ ASGI application: {settings.ASGI_APPLICATION}")

    # Check Channel Layers
    if hasattr(settings, 'CHANNEL_LAYERS'):
        channel_layers = settings.CHANNEL_LAYERS
        backend = channel_layers.get('default', {}).get('BACKEND', '')

        if 'InMemoryChannelLayer' in backend:
            print("⚠️  Using InMemory channel layer (not suitable for production)")
            return False
        elif 'RedisChannelLayer' in backend:
            print("✅ Using Redis channel layer (production ready)")
        else:
            print(f"⚠️  Unknown channel layer backend: {backend}")
            return False
    else:
        print("⚠️  CHANNEL_LAYERS not configured")
        return False

    return True

def check_https_configuration():
    """Check HTTPS configuration"""
    print("\n🔒 Checking HTTPS configuration...")

    use_https = getattr(settings, 'USE_HTTPS', False)

    if use_https or not settings.DEBUG:
        print("✅ HTTPS mode enabled")

        # Check SSL redirect
        if getattr(settings, 'SECURE_SSL_REDIRECT', False):
            print("✅ SSL redirect enabled")
        else:
            print("⚠️  SSL redirect disabled")

        # Check HSTS
        hsts_seconds = getattr(settings, 'SECURE_HSTS_SECONDS', 0)
        if hsts_seconds > 0:
            print(f"✅ HSTS enabled ({hsts_seconds} seconds)")
        else:
            print("⚠️  HSTS disabled")

        return True
    else:
        print("⚠️  HTTPS disabled (development mode)")
        return False

def check_environment_file():
    """Check if .env file exists and is properly configured"""
    print("\n📄 Checking environment file...")
    
    env_file = project_root / '.env'
    if not env_file.exists():
        print("❌ .env file not found!")
        print("   Copy .env.example to .env and configure it")
        return False
    
    print("✅ .env file exists")
    return True

def main():
    """Run all security checks"""
    print("🔍 Django Security Configuration Checker")
    print("=" * 50)

    checks = [
        check_environment_file,
        check_secret_key,
        check_debug_mode,
        check_allowed_hosts,
        check_database,
        check_security_headers,
        check_cors_configuration,
        check_websocket_configuration,
        check_https_configuration,
    ]

    passed = 0
    total = len(checks)

    for check in checks:
        if check():
            passed += 1

    print("\n" + "=" * 50)
    print(f"📊 Security Check Results: {passed}/{total} passed")

    if passed == total:
        print("🎉 All security checks passed! Your configuration looks good.")
    elif passed >= total * 0.7:
        print("⚠️  Most checks passed, but please address the warnings above.")
    else:
        print("❌ Several security issues found. Please fix them before production deployment.")

    print("\n📚 For more security guidance, see:")
    print("   https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/")
    print("   HTTPS Setup Guide: HTTPS_SETUP.md")
    print("   WebSocket Security: access_control/middleware.py")

if __name__ == '__main__':
    main()
